﻿using Compass.Wasm.Shared.Wms;
using Compass.WmsService.Domain;
using Compass.WmsService.Domain.Entities;
using Microsoft.EntityFrameworkCore;

namespace Compass.WmsService.Infrastructure;

public class WmsRepository:IWmsRepository
{
    private readonly WmsDbContext _context;
    public WmsRepository(WmsDbContext context)
    {
        _context = context;
    }

    #region Vendor
    public Task<IQueryable<Vendor>> GetVendorsAsync()
    {
        return Task.FromResult(_context.Vendors.AsQueryable());
    }

    public Task<Vendor?> GetVendorByIdAsync(Guid id)
    {
        return _context.Vendors.SingleOrDefaultAsync(x => x.Id.Equals(id));
    }

    public Task<Vendor?> GetVendorByNumberAsync(string number)
    {
        return _context.Vendors.SingleOrDefaultAsync(x => x.Number.Equals(number));
    }

    public Task<IQueryable<Vendor>> GetTop5VendorsByKeywordAsync(string? keyword)
    {
        return Task.FromResult(_context.Vendors.Where(x =>
             x.IsDeleted==false &&
             (string.IsNullOrEmpty(keyword)||
            x.Number.ToUpper().Contains(keyword.ToUpper())||
            x.Name.ToUpper().Contains(keyword.ToUpper())||
            x.Remarks!=null &&x.Remarks.ToUpper().Contains(keyword.ToUpper()))).OrderBy(x => x.Number).Take(5));
    }
    #endregion

    #region Cargo
    public Task<IQueryable<Cargo>> GetCargoesAsync()
    {
        return Task.FromResult(_context.Cargoes.AsQueryable());
    }

    public Task<Cargo?> GetCargoByIdAsync(Guid id)
    {
        return _context.Cargoes.SingleOrDefaultAsync(x => x.Id.Equals(id));
    }

    public Task<Cargo?> GetCargoByMtlNumberAsync(string mtlNumber)
    {
        return _context.Cargoes.SingleOrDefaultAsync(x => x.MtlNumber.Equals(mtlNumber.ToUpper()));
    }

    public Task<IQueryable<Cargo>> GetCargoesByAreaAsync(Warehouse_e warehouse, Area_e area, string ranks)
    {
        var location = $"{warehouse}-{area}{ranks}".ToUpper();
        return Task.FromResult(_context.Cargoes.Where(x =>
            x.IsDeleted==false && 
            x.Location != null && 
            x.Location.ToUpper().Contains(location)));
    }

    public Task<Cargo?> GetCargoByLocationAsync(string location)
    {
        return _context.Cargoes.SingleOrDefaultAsync(x => x.Location != null && x.Location.ToUpper().Contains(location.ToUpper()));
    }
    
    public Task<IQueryable<Cargo>> GetTop5CargoesByKeywordAsync(string? keyword)
    {
        return Task.FromResult(_context.Cargoes.Where(x =>x.IsDeleted==false && (string.IsNullOrEmpty(keyword)||
            x.MtlNumber.ToUpper().Contains(keyword.ToUpper())||x.Description!=null && x.Description.ToUpper().Contains(keyword.ToUpper()) ||x.Location!=null &&x.Location.ToUpper().Contains(keyword.ToUpper())||x.Remarks!=null &&x.Remarks.ToUpper().Contains(keyword.ToUpper()))).OrderBy(x=>x.MtlNumber).Take(5));
    }

    #endregion

    #region Location
    public Task<IQueryable<Location>> GetLocationsAsync()
    {
        return Task.FromResult(_context.Locations.AsQueryable());
    }

    public Task<Location?> GetLocationByIdAsync(Guid id)
    {
        return _context.Locations.SingleOrDefaultAsync(x => x.Id.Equals(id));
    }

    public Task<Location?> GetLocationByNameAsync(string name)
    {
        return _context.Locations.SingleOrDefaultAsync(x => x.Name.Equals(name.ToUpper()));
    }

    public Task<IQueryable<Location>> GetLocationsByAreaAsync(Warehouse_e warehouse, Area_e area,string ranks)
    {
        return Task.FromResult(_context.Locations.Where(x =>x.IsDeleted==false 
                                                            && x.Warehouse==warehouse && x.Area==area && x.Name.Contains(ranks.ToUpper())));
    }
    #endregion

    #region Inventory盘存记录
    public Task<IQueryable<Inventory>> GetInventoriesAsync()
    {
        return Task.FromResult(_context.Inventories.AsQueryable());
    }

    public Task<Inventory?> GetInventoryByIdAsync(Guid id)
    {
        return _context.Inventories.SingleOrDefaultAsync(x => x.Id.Equals(id));
    }

    public Task<Inventory?> GetInventoryLastByCargoAsync(Guid cargoId)
    {
        return Task.FromResult(_context.Inventories.Where(x =>x.IsDeleted==false && x.CargoId.Equals(cargoId)).OrderBy(x => x.CountTime)
            .LastOrDefault());
    }

    public Task<IQueryable<Inventory>> GetInventoriesByCargoAsync(Guid cargoId)
    {
        return Task.FromResult(_context.Inventories.Where(x =>x.IsDeleted==false && x.CargoId.Equals(cargoId)));
    }

    public Task<IQueryable<Inventory>> GetInventoriesByPeriodAsync(DateTime start, DateTime end)
    {
        return Task.FromResult(_context.Inventories.Where(x =>x.IsDeleted==false && x.CountTime>=start && x.CountTime<=end));
    }
    #endregion

    #region StockIn入库记录
    public  Task<IQueryable<StockIn>> GetStockInsAsync()
    {
        return Task.FromResult(_context.StockIns.AsQueryable());
    }

    public Task<StockIn?> GetStockInByIdAsync(Guid id)
    {
        return _context.StockIns.SingleOrDefaultAsync(x => x.Id.Equals(id));
    }

    public Task<IQueryable<StockIn>> GetStockInsFromLastByCargoAsync(Guid cargoId,DateTime last)
    {
        return Task.FromResult(_context.StockIns.Where(x =>x.IsDeleted==false&& x.CargoId.Equals(cargoId) && x.InTime>=last));
    }

    public Task<IQueryable<StockIn>> GetStockInsByCargoAsync(Guid cargoId)
    {
        return Task.FromResult(_context.StockIns.Where(x => x.IsDeleted==false&&  x.CargoId.Equals(cargoId)));
    }

    public Task<IQueryable<StockIn>> GetStockInsByPeriodAsync(DateTime start, DateTime end)
    {
        return Task.FromResult(_context.StockIns.Where(x => x.IsDeleted==false&&  x.InTime>=start && x.InTime<=end));
    }
    #endregion

    #region StockOut出库记录
    public Task<IQueryable<StockOut>> GetStockOutsAsync()
    {
        return Task.FromResult(_context.StockOuts.AsQueryable());
    }

    public Task<StockOut?> GetStockOutByIdAsync(Guid id)
    {
        return _context.StockOuts.SingleOrDefaultAsync(x => x.Id.Equals(id));
    }

    public Task<IQueryable<StockOut>> GetStockOutsFromLastByCargoAsync(Guid cargoId, DateTime last)
    {
        return Task.FromResult(_context.StockOuts.Where(x => x.IsDeleted==false&&  x.CargoId.Equals(cargoId) && x.OutTime>=last));
    }

    public Task<IQueryable<StockOut>> GetStockOutsByCargoAsync(Guid cargoId)
    {
        return Task.FromResult(_context.StockOuts.Where(x => x.IsDeleted==false&&  x.CargoId.Equals(cargoId)));
    }

    public Task<IQueryable<StockOut>> GetStockOutsByPeriodAsync(DateTime start, DateTime end)
    {
        return Task.FromResult(_context.StockOuts.Where(x => x.IsDeleted==false&&  x.OutTime>=start && x.OutTime<=end));
    } 
    #endregion

    
}